/*
 * Copyright (c) 2019-2020, https://api.iot.10086.cn/(https://gitee.com/cmcc-iot-api/iot-card-open-application/).
 */
package cn.iot.card.open.sim.service;

import cn.iot.card.open.constants.Constants;
import cn.iot.card.open.constants.ErrorCode;
import cn.iot.card.open.constants.UrlConstants;
import cn.iot.card.open.ec.dto.ResponseDto;
import cn.iot.card.open.modular.model.ResultDTO;
import cn.iot.card.open.modular.token.TokenService;
import cn.iot.card.open.pojo.page.LayuiPageFactory;
import cn.iot.card.open.pojo.page.LayuiPageInfo;
import cn.iot.card.open.sim.dto.UsageReqDTO;
import cn.iot.card.open.sim.dto.UsageRspDTO;
import cn.iot.card.open.sim.dto.voice.VoiceAmountInfo;
import cn.iot.card.open.sim.dto.voice.VoiceUsageApiRspDTO;
import cn.iot.card.open.util.ApiRequestUtil;
import cn.iot.card.open.util.CommonUtil;
import cn.iot.card.open.util.JsonUtil;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 按日查询语音使用量
 *
 * @author cmcc-iot-api
 * @date 20200221 18:25:29
 */
@Service
@Slf4j
public class VoiceUsageDailyService {

    /**
     * apiRequestUtil
     */
    @Autowired
    private ApiRequestUtil apiRequestUtil;

    /**
     * tokenService
     */
    @Autowired
    private TokenService tokenService;

    /**
     * 按日查询语音使用量.
     *
     * @param usageReqDTO 页面查询条件对象
     * @return 返回 layui page info 语音日使用量信息
     * @throws IOException
     * @author cmcc-iot-api
     * @date 20200221 18:26:45
     */
    public LayuiPageInfo queryVoiceUsageDaily(UsageReqDTO usageReqDTO) throws IOException {
        String accountId = usageReqDTO.getAccountId();
        String transId = CommonUtil.generateTransId(accountId);

        if (StringUtils.isBlank(accountId)) {
            log.info("[{}] accountId is null.", transId);
            return LayuiPageFactory.createEmptyPageInfo();
        }
        ResultDTO tokenResultDTO = doRequestVoiceUsageDaily(true, accountId, transId, usageReqDTO);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            return LayuiPageFactory.cteateErrorMsg(errorCode);
        }
        String responseStr = tokenResultDTO.getMsg();
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取状态码，状态码为12021，TOKEN超出规定使用时限或错误
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequestVoiceUsageDaily(false, accountId, transId, usageReqDTO);
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                return LayuiPageFactory.cteateErrorMsg(errorCode);
            }
        }
        responseStr = tokenResultDTO.getMsg();
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 解析api响应结果
        ResponseDto<VoiceUsageApiRspDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<VoiceUsageApiRspDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query VoiceUsageDaily error,error message is {}.", transId, result.getMessage());
            return LayuiPageFactory.cteateErrorMsg(ErrorCode.getByCode(code));
        }
        List<VoiceUsageApiRspDTO> voiceUsageApiRspDTOS = result.getResult();
        if (ToolUtil.isEmpty(voiceUsageApiRspDTOS)) {
            log.warn("[{}] query VoiceUsageDaily end,result is null.", transId);
            return LayuiPageFactory.createEmptyPageInfo();
        }
        List<VoiceAmountInfo> voiceAmountInfos = voiceUsageApiRspDTOS.get(0).getVoiceAmount();
        if (ToolUtil.isEmpty(voiceAmountInfos)) {
            log.warn("[{}] query VoiceUsageDaily end,result is null.", transId);
            return LayuiPageFactory.createEmptyPageInfo();
        }
        List<UsageRspDTO> usageRspDTOS = new ArrayList<>();
        for (VoiceAmountInfo voiceAmountInfo : voiceAmountInfos) {
            UsageRspDTO usageRspDTO = new UsageRspDTO();
            usageRspDTO.setIccid(usageReqDTO.getIccid());
            usageRspDTO.setImsi(usageReqDTO.getImsi());
            usageRspDTO.setMsisdn(usageReqDTO.getMsisdn());
            usageRspDTO.setQueryDate(usageReqDTO.getQueryDate());
            usageRspDTO.setVoice(voiceAmountInfo.getVoice());
            usageRspDTOS.add(usageRspDTO);
        }
        String voiceUsageRspDTOStr = JsonUtil.toJson(usageRspDTOS);
        List<Map<String,Object>> voiceUsageRspDTOMaps = JsonUtil.parseJson(voiceUsageRspDTOStr, new TypeReference<List<Map<String,Object>>>(){});
        Page page = LayuiPageFactory.defaultPage();
        page.setTotal(usageRspDTOS.size());
        page.setRecords(voiceUsageRspDTOMaps);
        return LayuiPageFactory.createPageInfo(page);
    }

    /**
     * request 请求
     *
     * @param tokenValid  是否生成新的token，false否，true是
     * @param accountId
     * @param transId
     * @param usageReqDTO
     * @return 返回 string
     * @throws IOException
     * @author cmcc-iot-api
     * @date 20200107 09:16:37
     */
    private ResultDTO doRequestVoiceUsageDaily(boolean tokenValid, String accountId, String transId, UsageReqDTO usageReqDTO) throws IOException {
        // 根据 accountId 查询 token
        ResultDTO tokenResultDTO = tokenService.getToken(tokenValid, accountId);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            return tokenResultDTO;
        }
        Map<String, String> parameterMap = new HashMap<>();
        parameterMap.put(Constants.REQUEST_PARAM_TOKEN, tokenResultDTO.getMsg());
        parameterMap.put(Constants.REQUEST_PARAM_TRANSID, transId);
        if (ToolUtil.isNotEmpty(usageReqDTO.getMsisdn())) {
            parameterMap.put(Constants.REQUEST_PARAM_MSISDNS, usageReqDTO.getMsisdn());
        } else if (ToolUtil.isNotEmpty(usageReqDTO.getIccid())) {
            parameterMap.put(Constants.REQUEST_PARAM_ICCIDS, usageReqDTO.getIccid());
        } else {
            parameterMap.put(Constants.REQUEST_PARAM_IMSIS, usageReqDTO.getImsi());
        }
        parameterMap.put(Constants.REQUEST_QUERY_DATE, usageReqDTO.getQueryDate());
        String methodUrl = apiRequestUtil.buildRequestUrl(parameterMap, UrlConstants.QUERY_SIM_VOICE_USAGE_DAILY_BATCH);
        log.info("[{}] query VoiceUsageDaily request url is {}.", transId, methodUrl);

        tokenResultDTO.setMsg(apiRequestUtil.doGet(methodUrl));
        return tokenResultDTO;
    }
}
